"""
Case Type   : reindex
Case Name   : 使用reindex重建索引的同时删除索引,看是否发生死锁
Create At   : 2022/08/30
Owner       : liu-tong-8848
Description :
    1.建表
    2.向表中插入数据
    3.创建索引1,2
    4.设置索引不可用,查询索引状态
    5.对表在线重建索引
    6.再次查询索引状态
    7.清理环境
Expect      :
    1.成功
    2.成功
    3.成功
    4.设置索引不可用成功,索引状态不可用
    5.成功
    6.索引状态不可用
    7.清理环境成功
History     :
"""

import os
import unittest
from testcase.utils.CommonSH import CommonSH
from testcase.utils.Constant import Constant
from testcase.utils.Logger import Logger


class SQL(unittest.TestCase):
    def setUp(self):
        self.logger = Logger()
        self.logger.info(f'-----{os.path.basename(__file__)} start-----')
        self.primary_sh = CommonSH('PrimaryDbUser')
        self.table = 't_reindex_concurrently_0069'
        self.index1 = 'i_reindex_concurrently_0069_1'
        self.index2 = 'i_reindex_concurrently_0069_2'
        self.Constant = Constant()

    def test_reindex(self):
        step1 = 'step1:建表 expect:成功'
        self.logger.info(step1)
        create_table = self.primary_sh.execut_db_sql(f'''
            drop  table if exists {self.table};
            create table {self.table}(id int,body text,title text,
            last_mod_date date)
            partition by range(id)(
                    partition p1 values less than(100000),
                    partition p2 values less than(200000),
                    partition p3 values less than(maxvalue)
            );''')
        self.logger.info(create_table)
        self.assertIn(self.Constant.TABLE_DROP_SUCCESS, create_table,
                      "执行失败" + step1)
        self.assertIn(self.Constant.CREATE_TABLE_SUCCESS, create_table,
                      "建分区表失败" + step1)

        step2 = 'step2:向表中插入数据 expect:成功'
        self.logger.info(step2)
        insert_data = self.primary_sh.execut_db_sql(
            f'''insert into {self.table} values(generate_series(1,500000), 
            'China, officially the  Republic of China (PRC)', 'China', 
            '2010-1-1');''')
        self.logger.info(insert_data)
        self.assertIn(self.Constant.INSERT_SUCCESS_MSG, insert_data,
                      "执行失败" + step2)

        step3 = 'step3:创建索引1,2 expect:创建索引1,2成功'
        self.logger.info(step3)
        create_index = self.primary_sh.execut_db_sql(
            f'''drop index if exists {self.index1};
            create index {self.index1} on {self.table}(body) local;
            drop index if exists {self.index2};
            create index {self.index2} on {self.table}(body) local;''')
        self.logger.info(create_index)
        self.assertIn(self.Constant.DROP_INDEX_SUCCESS_MSG, create_index,
                      "执行失败" + step3)
        self.assertIn(self.Constant.CREATE_INDEX_SUCCESS_MSG, create_index,
                      "执行失败" + step3)

        step4 = 'step4:设置索引2不可用,查询表索引状态 ' \
                'expect:设置索引2不可用成功,索引状态不可用'
        self.logger.info(step4)
        disable_index = self.primary_sh.execut_db_sql(
            f'''alter index {self.index2} unusable;
                \\d {self.table}''')
        self.logger.info(disable_index)
        self.assertIn(self.Constant.ALTER_INDEX_SUCCESS_MSG, disable_index,
                      "设置索引不可用失败" + step4)
        self.assertIn(f'"{self.index2}" btree (body) LOCAL TABLESPACE pg_'
                      f'default UNUSABLE', disable_index, "执行失败" +
                      step4)

        step5 = 'step5:对表在线重建索引 expect:成功'
        self.logger.info(step5)
        reindex = self.primary_sh.execut_db_sql(
            f'''reindex table concurrently {self.table};''')
        self.logger.info(reindex)
        self.assertIn('REINDEX', reindex, '执行失败' + step5)
        self.assertNotIn('ERROR', reindex, '执行失败' + step5)
        self.assertNotIn('WARNNING', reindex, '执行失败' + step5)

        step6 = 'step6:再次查询表索引状态 expect:索引状态不可用'
        self.logger.info(step6)
        index_status = self.primary_sh.execut_db_sql(
            f'''\\d {self.table}''')
        self.logger.info(index_status)
        self.assertIn(f'"{self.index2}" btree (body) LOCAL TABLESPACE pg_'
                      f'default UNUSABLE', index_status, "执行失败" +
                      step6)

    def tearDown(self):
        step7 = 'step7:清理环境 expect:清理环境成功'
        self.logger.info(step7)
        clean_environment = self.primary_sh.execut_db_sql(
            f'''drop table {self.table} cascade;''')
        self.logger.info(clean_environment)
        self.assertIn(self.Constant.TABLE_DROP_SUCCESS, clean_environment,
                      "执行失败" + step7)
        self.logger.info(f'-----{os.path.basename(__file__)} end-----')
